#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
语言处理器基类

提供所有语言处理器的抽象基类
"""

from abc import ABC, abstractmethod
from typing import Dict, List, Any
import re
from loguru import logger


class LanguageHandler(ABC):
    """
    语言处理器抽象基类

    所有具体的语言处理器都应该继承此类并实现其抽象方法
    """

    # 子类应该定义此属性，指定支持的文件扩展名列表
    file_extensions = []

    def __init__(self):
        """初始化语言处理器"""
        self._keywords = []
        self._regex_patterns = {}
        self._compiled_patterns = {}  # 存储预编译的正则表达式
        self._tag_styles = {}
        self.is_compiled = False  # 添加编译状态标志
        self._setup_language()
        # 不再在初始化时自动编译正则表达式
        # self._compile_patterns()

    @abstractmethod
    def _setup_language(self):
        """
        设置语言特定的规则

        子类必须实现此方法来定义：
        - 关键字列表
        - 正则表达式模式
        - 标签样式
        """
        pass

    def _compile_patterns(self):
        """预编译所有正则表达式模式"""
        # 如果已经编译过，直接返回
        if self.is_compiled:
            return

        # 获取正则表达式标志（如果子类定义了）
        regex_flags = getattr(self, "_regex_flags", {})

        for name, pattern in self._regex_patterns.items():
            try:
                # 获取该模式的标志，默认为0（无特殊标志）
                flags = regex_flags.get(name, 0)
                self._compiled_patterns[name] = re.compile(
                    pattern, flags | re.MULTILINE
                )
                logger.debug(f"正则表达式 '{name}' 编译成功，标志: {flags}")

            except re.error as e:
                logger.warning(f"正则表达式 '{name}' 编译失败: {e}, 模式: {pattern}")
                # 如果编译失败，跳过该模式，不添加到编译后的模式字典中
                # 这样可以避免后续使用无效的正则表达式
                # 记录详细错误信息以便调试
                logger.debug(
                    f"失败的正则表达式详情: 名称={name}, 模式={pattern}, 错误={e}"
                )
            except Exception as e:
                # 捕获其他可能的异常，防止程序崩溃
                logger.error(
                    f"编译正则表达式 '{name}' 时发生意外错误: {e}, 模式={pattern}"
                )
                logger.debug(
                    f"意外错误详情: 名称={name}, 模式={pattern}, 错误类型={type(e).__name__}"
                )

        # 标记为已编译
        self.is_compiled = True

    def ensure_compiled(self):
        """确保已编译正则表达式（公共接口）"""
        if not self.is_compiled:
            self._compile_patterns()
        return self.is_compiled

    def get_keywords(self) -> List[str]:
        """
        获取关键字列表

        Returns:
            List[str]: 关键字列表
        """
        return self._keywords

    def get_regex_patterns(self) -> Dict[str, str]:
        """
        获取正则表达式模式字典

        Returns:
            Dict[str, str]: 标签名到正则表达式的映射
        """
        return self._regex_patterns

    def get_compiled_patterns(self) -> Dict[str, Any]:
        """
        获取预编译的正则表达式字典

        Returns:
            Dict[str, Any]: 标签名到预编译正则表达式的映射
        """
        # 确保已编译
        self.ensure_compiled()
        return self._compiled_patterns

    def get_tag_styles(self) -> Dict[str, Dict[str, Any]]:
        """
        获取标签样式字典

        Returns:
            Dict[str, Dict[str, Any]]: 标签名到样式属性的映射
        """
        return self._tag_styles

    def get_pattern_order(self) -> List[str]:
        """
        获取模式处理顺序列表

        Returns:
            List[str]: 模式处理顺序列表
        """
        # 按字母顺序排序，确保一致性和可预测性
        return sorted(list(self._regex_patterns.keys()))

    @classmethod
    def get_file_extensions(cls) -> List[str]:
        """
        获取支持的文件扩展名列表

        Returns:
            List[str]: 支持的文件扩展名列表
        """
        return cls.file_extensions

    @classmethod
    @abstractmethod
    def get_language_name(cls) -> str:
        """
        获取语言处理器名称

        Returns:
            str: 语言处理器名称，如"go"、"python"等
        """
        pass
